package com.app.util;

import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;

import org.joda.time.DateTime;

import com.google.gson.internal.LinkedTreeMap;

public class DateUtil {

    public static String formart(Date date, String parse) {
        if (date == null) {
            return "";
        }

        SimpleDateFormat sdf = new SimpleDateFormat(parse);
        return sdf.format(date);
    }

    /**
     * yyyy-MM-dd
     * 
     * @param date
     * @return
     * @author zhangxf
     * @created 2017年3月22日 下午5:31:03
     */
    public static String yyyyMMddLine(Date date) {
        if (date == null) {
            return "";
        }
        return new SimpleDateFormat("yyyy-MM-dd").format(date);
    }

    // 获取今天的开始时间
    public static Long getStartTime() {
        Calendar todayStart = Calendar.getInstance();
        todayStart.set(Calendar.HOUR, 0);
        todayStart.set(Calendar.MINUTE, 0);
        todayStart.set(Calendar.SECOND, 0);
        todayStart.set(Calendar.MILLISECOND, 0);
        return todayStart.getTime().getTime();
    }

    // 获取本月开始时间
    public static Date getMounthStartTime() {
        Date date = new Date();
        SimpleDateFormat sdf1 = new SimpleDateFormat("yyyyMM");
        String dates = sdf1.format(date) + "01";
        SimpleDateFormat sdf2 = new SimpleDateFormat("yyyyMMdd");
        try {
            return sdf2.parse(dates);
        } catch (ParseException e) {
            e.printStackTrace();
            return null;
        }
    }

    public static Date getStartTime(Date d) {
        SimpleDateFormat sdf1 = new SimpleDateFormat("yyyyMMdd");
        SimpleDateFormat sdf2 = new SimpleDateFormat("yyyyMMdd HH:mm:ss,sss");
        String s = sdf1.format(d);
        s = s + " 00:00:00,0";
        try {
            return sdf2.parse(s);
        } catch (ParseException e) {
            e.printStackTrace();
            return null;
        }
    }

    // 获取今天的结束时间
    public static Long getEndTime() {
        Calendar todayEnd = Calendar.getInstance();
        todayEnd.set(Calendar.HOUR, 23);
        todayEnd.set(Calendar.MINUTE, 59);
        todayEnd.set(Calendar.SECOND, 59);
        todayEnd.set(Calendar.MILLISECOND, 999);
        return todayEnd.getTime().getTime();
    }

    public static Date fomart(String date, String parse) {
        SimpleDateFormat sdf = new SimpleDateFormat(parse);
        try {
            return sdf.parse(date);
        } catch (ParseException e) {
            e.printStackTrace();
            return null;
        }
    }

    public static String fomart(Date date, String parse) {
        if (date == null) {
            return "";
        }

        SimpleDateFormat sdf = new SimpleDateFormat(parse);
        return sdf.format(date);
    }

    public static Date removeHm(Date date) {
        if (date == null) {
            return null;
        }

        SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMdd");

        try {
            return sdf.parse(sdf.format(date));
        } catch (ParseException e) {
            e.printStackTrace();
            return null;
        }
    }

    public static Integer getDaysBetween(Date startDate, Date endDate) {
        Calendar fromCalendar = Calendar.getInstance();
        fromCalendar.setTime(startDate);
        fromCalendar.set(Calendar.HOUR_OF_DAY, 0);
        fromCalendar.set(Calendar.MINUTE, 0);
        fromCalendar.set(Calendar.SECOND, 0);
        fromCalendar.set(Calendar.MILLISECOND, 0);

        Calendar toCalendar = Calendar.getInstance();
        toCalendar.setTime(endDate);
        toCalendar.set(Calendar.HOUR_OF_DAY, 0);
        toCalendar.set(Calendar.MINUTE, 0);
        toCalendar.set(Calendar.SECOND, 0);
        toCalendar.set(Calendar.MILLISECOND, 0);

        Long days = (toCalendar.getTime().getTime() - fromCalendar.getTime().getTime()) / (1000 * 60 * 60 * 24);
        return days.intValue();
    }

    /**
     * 根据日期获取周几
     *
     * @param date
     *        日期
     * @return 周几：1-6代表周一到周六；7，代表周日
     */
    public static int getWeekNum(Date date) {
        Calendar cal = Calendar.getInstance();
        cal.setTime(date);
        // 原生函数是从周日算作每周的第一天的,所以需要转换
        int week = cal.get(Calendar.DAY_OF_WEEK) - 1;
        return week == 0 ? 7 : week;
    }

    /**
     * 是否包含相同日期
     *
     * @param startDate
     * @param endDate
     * @param checkStartDate
     * @param checkEndDate
     * @return
     */
    public static boolean isHasSameDay(Date startDate, Date endDate, Date checkStartDate, Date checkEndDate) {
        if (startDate == null || endDate == null) {
            return false;
        }
        if (checkStartDate.compareTo(startDate) >= 0 && checkStartDate.compareTo(endDate) <= 0) {
            return true;
        }
        if (checkEndDate.compareTo(startDate) >= 0 && checkEndDate.compareTo(endDate) <= 0) {
            return true;
        }
        return false;
    }

    public static Date now() {
        return new Date();
    }

    // 获取年龄
    public static Long howYear(Date startTime) {
        if (null == startTime) {
            return null;
        }
        // 时间单位(如：不足1天(24小时) 则返回0)，开始时间，结束时间
        Date nowTime = new Date();
        Long ltime = nowTime.getTime() - startTime.getTime();
        System.out.println(ltime / (365 * 12 * 24 * 60 * 60 * 1000));
        return ltime / 365 * 12 * 24 * 60 * 60 * 1000;
    }

    public static Integer getAgeByBirthday(Date birthday) {
        if (null == birthday) {
            return null;
        }
        Calendar cal = Calendar.getInstance();

        if (cal.before(birthday)) {
            throw new IllegalArgumentException("The birthDay is before Now.It's unbelievable!");
        }

        int yearNow = cal.get(Calendar.YEAR);
        int monthNow = cal.get(Calendar.MONTH) + 1;
        int dayOfMonthNow = cal.get(Calendar.DAY_OF_MONTH);

        cal.setTime(birthday);
        int yearBirth = cal.get(Calendar.YEAR);
        int monthBirth = cal.get(Calendar.MONTH) + 1;
        int dayOfMonthBirth = cal.get(Calendar.DAY_OF_MONTH);

        int age = yearNow - yearBirth;

        if (monthNow <= monthBirth) {
            if (monthNow == monthBirth) {
                // monthNow==monthBirth
                if (dayOfMonthNow < dayOfMonthBirth) {
                    age--;
                }
            } else {
                // monthNow>monthBirth
                age--;
            }
        }
        return age;
    }

    /**
     * 获取两个日期之间的所有天
     * 
     * @param startDate
     * @param endDate
     * @return
     */
    public static LinkedTreeMap<String, String> getDayBetween(String startDate, String endDate) {
        LinkedTreeMap<String, String> map = new LinkedTreeMap<String, String>();
        DateTime sDateTime = DateTime.parse(startDate);
        DateTime eDateTime = DateTime.parse(endDate);
        // 格式化为年月
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");

        Calendar min = Calendar.getInstance();
        Calendar max = Calendar.getInstance();

        min.setTimeInMillis(sDateTime.getMillis());
        min.set(min.get(Calendar.YEAR), min.get(Calendar.MONTH), 1);

        max.setTimeInMillis(eDateTime.getMillis());
        max.set(max.get(Calendar.YEAR), max.get(Calendar.MONTH), 2);

        Calendar curr = min;
        while (curr.before(max)) {
            map.put(sdf.format(curr.getTime()), "");
            curr.add(Calendar.DAY_OF_YEAR, 1);
        }

        return map;
    }

    /**
     * 获取两个日期之间的所有月份
     * 
     * @param startDate
     * @param endDate
     * @return
     */
    public static LinkedTreeMap<String, String> getMonthBetween(String startDate, String endDate) {
        LinkedTreeMap<String, String> map = new LinkedTreeMap<String, String>();
        DateTime sDateTime = DateTime.parse(startDate);
        DateTime eDateTime = DateTime.parse(endDate);
        // 格式化为年月
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM");

        Calendar min = Calendar.getInstance();
        Calendar max = Calendar.getInstance();

        min.setTimeInMillis(sDateTime.getMillis());
        min.set(min.get(Calendar.YEAR), min.get(Calendar.MONTH), 1);

        max.setTimeInMillis(eDateTime.getMillis());
        max.set(max.get(Calendar.YEAR), max.get(Calendar.MONTH), 2);

        Calendar curr = min;
        while (curr.before(max)) {
            map.put(sdf.format(curr.getTime()), "");
            curr.add(Calendar.MONTH, 1);
        }

        return map;
    }

    /**
     * 获取两个日期之间的所有年
     * 
     * @param startDate
     * @param endDate
     * @return
     */
    public static LinkedTreeMap<String, String> getYearBetween(String startDate, String endDate) {
        LinkedTreeMap<String, String> map = new LinkedTreeMap<String, String>();
        DateTime sDateTime = DateTime.parse(startDate);
        DateTime eDateTime = DateTime.parse(endDate);
        // 格式化为年月
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy");

        Calendar min = Calendar.getInstance();
        Calendar max = Calendar.getInstance();

        min.setTimeInMillis(sDateTime.getMillis());
        min.set(min.get(Calendar.YEAR), min.get(Calendar.MONTH), 1);

        max.setTimeInMillis(eDateTime.getMillis());
        max.set(max.get(Calendar.YEAR), max.get(Calendar.MONTH), 2);

        Calendar curr = min;
        while (curr.before(max)) {
            map.put(sdf.format(curr.getTime()), "");
            curr.add(Calendar.YEAR, 1);
        }

        return map;
    }

    public static Date getDateDayStart(Date date) {
        Calendar cal = Calendar.getInstance();
        cal.setTime(date);

        cal.set(Calendar.HOUR, 0);
        cal.set(Calendar.HOUR_OF_DAY, 0);
        cal.clear(Calendar.MINUTE);
        cal.clear(Calendar.SECOND);
        cal.clear(Calendar.MILLISECOND);

        return cal.getTime();
    }

    public static Date getDateDayEnd(Date date) {
        Calendar cal = Calendar.getInstance();
        cal.setTime(date);

        cal.set(Calendar.HOUR_OF_DAY, 23);
        cal.set(Calendar.MINUTE, 59);
        cal.set(Calendar.SECOND, 59);
        cal.clear(Calendar.MILLISECOND);

        return cal.getTime();
    }

    public static Date getDayStartNullOfNow(Date date) {
        Calendar cal = Calendar.getInstance();
        cal.setTime(date == null ? new Date() : date);

        cal.set(Calendar.HOUR_OF_DAY, 0);
        cal.clear(Calendar.MINUTE);
        cal.clear(Calendar.SECOND);
        cal.clear(Calendar.MILLISECOND);

        return cal.getTime();
    }

    public static Date getDayEndNullOfNow(Date date) {
        Calendar cal = Calendar.getInstance();
        cal.setTime(date == null ? new Date() : date);

        cal.set(Calendar.HOUR_OF_DAY, 23);
        cal.set(Calendar.MINUTE, 59);
        cal.set(Calendar.SECOND, 59);
        cal.set(Calendar.MILLISECOND, 999);

        return cal.getTime();
    }
    
    public static void main(String[] args) throws ParseException {
        SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        Date parse = df.parse("2017-06-07 10:10:00");
        
        Date dayStartNullOfNow = getDayStartNullOfNow(parse);
        
        System.out.println(df.format(dayStartNullOfNow));
    }
    

}
